/**
 * 
 */
package lt.ruta;

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.List;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

import lt.ruta.data.Messages;
import lt.ruta.data.Record;
import lt.ruta.data.Table;
import lt.ruta.data.table.FileTableSender;
import lt.ruta.data.table.TableSender;
import lt.ruta.ui.DialogForm;
import lt.ruta.ui.DirectoryForm;
import lt.ruta.ui.EnterForm;
import lt.ruta.ui.InfoForm;
import lt.ruta.ui.SenderForm;

/**
 * @author Vincentas
 *
 */
public class RutaMidlet extends MIDlet implements CommandListener {
	
	private Display display;

	private EnterForm enterForm = null;
	
	private InfoForm infoForm = null;
	
	private SenderForm senderForm = null; 
	
	private DirectoryForm directoryForm = null;
	
	private Command okCommand = null;
	
	private Command sendCommand = null;
	
	private Command exitCommand = null;
	
	private Command infoCommand = null;
	
	private Command enterCommand = null;
	
	private Command backCommand = null;
	
	private Table table = null;
	
	private Alert savedAlert = null;
	
	private Alert failedAlert = null;
	
	private Command clearCommand = null;
	
	public static RutaMidlet instance;
	
	/**
	 * @return the clearCommand
	 */
	public Command getClearCommand() {
		if (clearCommand == null) {			
			clearCommand = new Command(Messages.get("command.clear"), Command.SCREEN, 4);
			
		}

		return clearCommand;
	}

	/**
	 * @return the savedAlert
	 */
	public Alert getSavedAlert() {
		if (savedAlert == null) {
			savedAlert = new Alert(
					Messages.get("savedAlert.title"),
					Messages.get("savedAlert.message"),
					null, AlertType.INFO);
			
		}

		return savedAlert;
	}

	/**
	 * @return the failedAlert
	 */
	public Alert getFailedAlert() {
		if (failedAlert == null) {
			failedAlert = new Alert(
					Messages.get("failedAlert.title"),
					Messages.get("failedAlert.message"),
					null, AlertType.ERROR);
			
		}

		return failedAlert;
	}

	/**
	 * @return the directoryForm
	 */
	public DirectoryForm getDirectoryForm() {
		if (directoryForm == null) {
			directoryForm = new DirectoryForm(Messages.get("directoryForm.title"));
			
			directoryForm.removeCommand(List.SELECT_COMMAND);
			directoryForm.addCommand(getEnterCommand());
			directoryForm.addCommand(getOkCommand());
			directoryForm.addCommand(getBackCommand());
			
			directoryForm.setCommandListener(this);
		}

		return directoryForm;
	}

	/**
	 * @return the directoryForm
	 */
	public SenderForm getSendForm() {
		if (senderForm == null) {
			senderForm = new SenderForm(Messages.get("senderForm.title"));
			
		}

		return senderForm;
	}

	/**
	 * @return the enterForm
	 */
	public EnterForm getEnterForm() {
		if (enterForm == null) {
			enterForm = new EnterForm(Messages.get("enterForm.title"));		
			
			enterForm.addCommand(getOkCommand());
			enterForm.addCommand(getSendCommand());		
			enterForm.addCommand(getExitCommand());
			enterForm.addCommand(getInfoCommand());
			enterForm.addCommand(getClearCommand());
			
			enterForm.setCommandListener(this);
		}

		return enterForm;
	}
	
	/**
	 * @return the infoForm
	 */
	public InfoForm getInfoForm() {
		if (infoForm == null) {
			infoForm = new InfoForm(Messages.get("infoForm.title"), getTable());
			
			infoForm.addCommand(getOkCommand());
			
			infoForm.setCommandListener(this);
		}

		return infoForm;
	}
	
	/**
	 * @return the backCommand
	 */
	public Command getBackCommand() {
		if (backCommand == null) {
			backCommand = new Command(Messages.get("command.back"), Command.CANCEL, 5);			
		}

		return backCommand;
	}

	/**
	 * @return the enterCommand
	 */
	public Command getEnterCommand() {
		if (enterCommand == null) {
			enterCommand = new Command(Messages.get("command.enter"), Command.ITEM, 4);			
		}

		return enterCommand;
	}

	/**
	 * @return the infoCommand
	 */
	public Command getInfoCommand() {
		if (infoCommand == null) {
			infoCommand = new Command(Messages.get("command.info"), Command.SCREEN, 5);
		}

		return infoCommand;
	}

	/**
	 * @return the okCommand
	 */
	public Command getOkCommand() {
		if (okCommand == null) {
			okCommand = new Command(Messages.get("command.ok"), Command.ITEM, 0);			
		}

		return okCommand;
	}
	
	/**
	 * @return the exitCommand
	 */
	public Command getExitCommand() {
		if (exitCommand == null) {
			exitCommand = new Command(Messages.get("command.exit"), Command.EXIT, 9);
			
		}

		return exitCommand;
	}

	/**
	 * @return the exportCommand
	 */
	public Command getSendCommand() {
		if (sendCommand == null) {
			sendCommand = new Command(Messages.get("command.send"), Command.SCREEN, 1);
			
		}

		return sendCommand;
	}
	
	/**
	 * @return the display
	 */
	public Display getDisplay() {
		if (display == null) {
			display = Display.getDisplay(this);
			
		}

		return display;
	}
	
	/**
	 * @return the table
	 */
	public Table getTable() {
		if (table == null) {
			table = new Table();
			
		}

		return table;
	}

	/* (non-Javadoc)
	 * @see javax.microedition.lcdui.CommandListener#commandAction(javax.microedition.lcdui.Command, javax.microedition.lcdui.Displayable)
	 */
	public void commandAction(Command c, Displayable d) {
		if (d.equals(getEnterForm())) {
			if (c.equals(getOkCommand())) {
				onNewRecord();
			} else if (c.equals(getInfoCommand())) {
				getInfoForm().update();
				getDisplay().setCurrent(getInfoForm());
			} else if (c.equals(getSendCommand())) {
				getDisplay().setCurrent(getDirectoryForm());
			} else if (c.equals(getExitCommand())) {
				onExit();				
			} else if (c.equals(getClearCommand())) {
				onTableClear();
			}
		} else if (d.equals(getInfoForm())) {
			if (c.equals(getOkCommand())) {
				getDisplay().setCurrent(getEnterForm());
			}
		} else if (d.equals(getDirectoryForm())) {
			if (c.equals(getEnterCommand())) {
				getDirectoryForm().setPath(getDirectoryForm().getSelectedPath());
			} else if (c.equals(getOkCommand())) {
				onSaveTable();
			} else if (c.equals(getBackCommand())) {
				getDirectoryForm().setPath(DirectoryForm.getParent(getDirectoryForm().getPath()));
			}
		}
	}

	/**
	 * 
	 */
	private void onExit() {
		getDisplay().setCurrent(new DialogForm(Messages.get("dialog.exit.title"), Messages.get("dialog.exit.message")) {
		
			public void onYes() {
				notifyDestroyed();		
			}
		
			public void onCancel() {
				getDisplay().setCurrent(getEnterForm());
			}
		
		});
	}

	/**
	 * 
	 */
	private void onSaveTable() {
		TableSender tableSender = new FileTableSender(getDirectoryForm().getSelectedPath() + "out.txt");
		tableSender.send(getTable());
		onTableClear();		
	}

	/**
	 * 
	 */
	private void onNewRecord() {
		Record record = getEnterForm().getRecord();
		if (record != null) {
			getTable().addRecord(record);
			
			getDisplay().setCurrent(getSavedAlert(), getEnterForm());
			getEnterForm().reset();					
		} else {					
			getDisplay().setCurrent(getFailedAlert(), getEnterForm());
		}
	}

	private void onTableClear() {
		display.setCurrent(new DialogForm(Messages.get("dialog.clearTable.title"), Messages.get("dialog.clearTable.message")) {
		
			public void onYes() {
				getTable().clear();
				display.setCurrent(getEnterForm());
			}
		
			public void onCancel() {
				display.setCurrent(getEnterForm());
			}
		
		});
	}
	
	/**
	 * 
	 */
	public RutaMidlet() {
		instance = this;
	}

	/* (non-Javadoc)
	 * @see javax.microedition.midlet.MIDlet#destroyApp(boolean)
	 */
	protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see javax.microedition.midlet.MIDlet#pauseApp()
	 */
	protected void pauseApp() {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see javax.microedition.midlet.MIDlet#startApp()
	 */
	protected void startApp() throws MIDletStateChangeException {
		getDisplay().setCurrent(getEnterForm());

	}
	
	public void showError(Throwable throwable) {
		Displayable displayable = display.getCurrent();
		display.setCurrent(getErrorAlert(throwable), displayable);		
	}
	
	private Alert getErrorAlert(Throwable throwable) {		
		Alert alert = new Alert(
				throwable.getMessage(),
				throwable.getMessage(),
				null, AlertType.ERROR);
		
		return alert;
	}
	

}
